package de.szut.sudoku.gui.sudokufield;

import java.awt.Color;
import java.awt.event.KeyEvent;

import javax.swing.JLabel;

import de.szut.sudoku.gui.MainFrame;

/**
 * Class for the movement key input
 * 
 * @author Marc Huisinga
 * 
 */
public class SudokuButtonKeyListener extends SudokuKeyListener {
	private SudokuFieldLabel[][] sudokuLabels;
	private SudokuFieldLabel currentSelectedLabel;
	private Color switchColor;
	private Color defaultColor;
	private int[] labelPosition;
	private JLabel source;
	private SudokuButtonClickListener associatedClickListener;

	public SudokuButtonKeyListener(
			SudokuButtonClickListener associatedClickListener,
			SudokuFieldLabel[][] sudokuLabels) {
		this.associatedClickListener = associatedClickListener;
		this.sudokuLabels = sudokuLabels;
		defaultColor = SudokuFieldLabel.DEFAULTCOLOR;
		switchColor = SudokuFieldLabel.SWITCHCOLOR;
	}

	/**
	 * Gets the position in an array of labels from the label
	 */
	private void getLabelPosition() {
		labelPosition = new int[2];
		int[] currentIndex = { 0, 0 };
		for (SudokuFieldLabel[] currentLabelLine : sudokuLabels) {
			for (SudokuFieldLabel currentLabel : currentLabelLine) {
				if (currentLabel == source) {
					labelPosition[0] = currentIndex[0];
					labelPosition[1] = currentIndex[1];
				}
				currentIndex[0]++;
			}
			currentIndex[0] = 0;
			currentIndex[1]++;
		}
	}

	/**
	 * Switches the label
	 * 
	 * @param xSwitchIndex
	 * @param ySwitchIndex
	 */
	private void switchSelectedLabel(int xSwitchIndex, int ySwitchIndex) {
		int[] maxIndexes = { sudokuLabels.length - 1,
				sudokuLabels[0].length - 1 };
		// Moves
		if (labelPosition[1] + xSwitchIndex >= 0
				&& labelPosition[0] + ySwitchIndex >= 0
				&& labelPosition[1] + xSwitchIndex <= maxIndexes[0]
				&& labelPosition[0] + ySwitchIndex <= maxIndexes[1]) {
			currentSelectedLabel = sudokuLabels[labelPosition[1] + xSwitchIndex][labelPosition[0]
					+ ySwitchIndex];
			// Moves to the respective other side of the borders
		} else if (!(labelPosition[1] + xSwitchIndex >= 0)) {
			currentSelectedLabel = sudokuLabels[maxIndexes[0]][labelPosition[0]
					+ ySwitchIndex];
		} else if (!(labelPosition[0] + ySwitchIndex >= 0)) {
			currentSelectedLabel = sudokuLabels[labelPosition[1] + xSwitchIndex][maxIndexes[1]];
		} else if (!(labelPosition[1] + xSwitchIndex <= maxIndexes[0])) {
			currentSelectedLabel = sudokuLabels[0][labelPosition[0]
					+ ySwitchIndex];
		} else if (!(labelPosition[0] + ySwitchIndex <= maxIndexes[1])) {
			currentSelectedLabel = sudokuLabels[labelPosition[1] + xSwitchIndex][0];
		} else {
			System.out.println("Error occured!");
		}
		// Sets the current label
		associatedClickListener.setCurrentSelectedLabel(currentSelectedLabel);
		source.setBackground(defaultColor);
		currentSelectedLabel.setBackground(switchColor);
		currentSelectedLabel.requestFocus();

		// Cleans mistakes that happen when two inputs are interfering each
		// other
		for (SudokuFieldLabel[] currentLabelLine : sudokuLabels) {
			for (SudokuFieldLabel currentLabel : currentLabelLine) {
				if (currentLabel.getBackground() == switchColor
						&& !(currentLabel == currentSelectedLabel)) {
					currentLabel.setBackground(defaultColor);
				}
			}
		}
	}

	/**
	 * Key event for movement
	 */
	@Override
	public void keyPressed(KeyEvent keyEvent) {
		setKeyEvent(keyEvent);
		source = (JLabel) getKeyEvent().getSource();
		getLabelPosition();
		// Move upwards
		if (keyEvent.getKeyCode() == KeyEvent.VK_UP
				|| keyEvent.getKeyCode() == KeyEvent.VK_KP_UP
				|| keyEvent.getKeyCode() == KeyEvent.VK_W) {
			switchSelectedLabel(-1, 0);
			// Move downwards
		} else if (keyEvent.getKeyCode() == KeyEvent.VK_DOWN
				|| keyEvent.getKeyCode() == KeyEvent.VK_KP_DOWN
				|| keyEvent.getKeyCode() == KeyEvent.VK_S) {
			switchSelectedLabel(1, 0);
			// Move to the right
		} else if (keyEvent.getKeyCode() == KeyEvent.VK_RIGHT
				|| keyEvent.getKeyCode() == KeyEvent.VK_KP_RIGHT
				|| keyEvent.getKeyCode() == KeyEvent.VK_D) {
			switchSelectedLabel(0, 1);
			// Move to the left
		} else if (keyEvent.getKeyCode() == KeyEvent.VK_LEFT
				|| keyEvent.getKeyCode() == KeyEvent.VK_KP_LEFT
				|| keyEvent.getKeyCode() == KeyEvent.VK_A) {
			switchSelectedLabel(0, -1);
		}

		// Refresh the frame
		MainFrame.getInstance().revalidate();
		MainFrame.getInstance().repaint();
	}
}
